%% Global parameters
global schedPerf;

schedPerf.procTime = [];
schedPerf.iterations = [];

MaxIaRelationNr = 2^13-1;

if ~exist('globalcntr_range', 'var')
  globalcntr_range = 1:100;
  %globalcntr_range = 1;
end

if ~exist('method_range', 'var')
  method_range = 1:2;
end

%% Simulation Scenarios

if ~exist('simulationScenario', 'var')
  simulationScenario = 1;
end

if ~exist('intervals_range', 'var')
  switch simulationScenario
    case 1
      intervals_range = [10 40 160 320];
    otherwise
      intervals_range = 80;
  end
end

if ~exist('relations_range', 'var')
  switch simulationScenario
    case 2
      relations_range = [1/16 1/8 1/2 1];
    otherwise
      relations_range = 1/4;
  end
end

if ~exist('operators_range', 'var')
  switch simulationScenario
    case 3
      operators_range = [IA_Relation([1 0 0 0 0 0 0; 1 0 0 0 0 0 0])...
                         IA_Relation([1 0 1 1 0 0 0; 1 0 1 1 0 0 0])...
                         IA_Relation([1 1 1 1 1 1 0; 1 1 1 1 1 1 0])...
                         IA_Relation([1 1 1 1 1 1 1; 1 1 1 1 1 1 1])...
                         ];
      operators_print = [2/13 6/13 12/13 13/13];
    otherwise
      operators_range =  IA_Relation([1 1 1 1 0 0 0; 1 1 1 1 0 0 0]);
      operators_print =  8/13;
  end
end

%% Open logfile
filename = sprintf('iaPcEval_%s.csv', datestr(now,'yyyymmddTHHMMSS_FFF'));
logfile = fopen(filename, 'at');

fprintf(logfile, 'globalcntr, algorithm, intervals, relations, operators, attempts, procTimeSamples, procTimeTotal, procTimeAve, procTimeDev, iterationsSamples, iterationsTotal, iterationsAve, iterationsDev\n');
fclose(logfile);

%% Initialise IA Hogge Matrices
IA_Relation1 = IA_Relation_From_Number(randi(MaxIaRelationNr));
IA_Relation2 = IA_Relation_From_Number(randi(MaxIaRelationNr));
IA_Relation3 = IA_Relation_Dummy();
[IA_Relation] = IA_Relation_Constraints_Hogge(IA_Relation1, IA_Relation2, IA_Relation3);
clear IA_Relation1; clear IA_Relation2; clear IA_Relation3; clear IA_Relation;

for globalcntr = globalcntr_range
  
  randStream = RandStream.create('mt19937ar','seed',globalcntr);
  RandStream.setGlobalStream(randStream);
    
  for intervals = intervals_range
    
    for relations = relations_range
      
      for opIndex = 1:length(operators_range)
    
        operators = operators_range(opIndex);
        
        for method = method_range

          fprintf(1,' -------- Run number %d Method %d Intervals %d Relations %.3f Operators %.3f -------------\n', globalcntr, method, intervals, relations, operators_print(opIndex));

          start = tic;

          schedPerf.procTime = [];
          schedPerf.iterations = [];

          iaId = 1;
          iaNetwork = IA_Network_Empty();
          iaInterval = IA_Interval(sprintf('T%i', iaId), iaId);
          iaNetwork = IA_Network_Add_Interval(iaNetwork, iaInterval);

          iaNetworkTemp = iaNetwork;
          iaNetworkNodes = IA_Network_Nodes(iaNetwork);
          consistent = 1;

          while iaId < intervals
            iterationStart = tic;

            iaId = iaId + 1;
            iaInterval = IA_Interval(sprintf('T%i', iaId), iaId);
            iaNetworkTemp = IA_Network_Add_Interval(iaNetwork, iaInterval);

            iaIdRels = randperm(iaNetworkNodes);
            iaIdRels = iaIdRels(1:floor(length(iaIdRels) * relations));

            for iaIdRel = iaIdRels

              iaRelation = IA_Relation_Intersect(IA_Relation_From_Number(randi(MaxIaRelationNr)), operators);

              switch method
                case 1 % Hogge IA PC
                  [iaNetworkTemp, consistent] = IA_Network_Path_Consistency_Hogge(iaNetworkTemp, iaNetworkNodes + 1, iaIdRel, iaRelation);
                case 2 % Parallel IA PC (Hogge)
                  [iaNetworkTemp, consistent] = IA_Network_Path_Consistency_Parallel(iaNetworkTemp, iaNetworkNodes + 1, iaIdRel, iaRelation);
              end

              if ~consistent
                break;
              end
            end

            if consistent
              iaNetwork = iaNetworkTemp;
            end

            schedPerf.procTime = [schedPerf.procTime toc(iterationStart)];
            iaNetworkNodes = IA_Network_Nodes(iaNetwork);
          end

          toc(start)

          reset(RandStream.getGlobalStream);
          logfile = fopen(filename, 'at');
          fprintf(logfile, '%d, %d, %d, %f, %f, %d, %d, %f, %f, %f, %d, %d, %f, %f\n', globalcntr, method, intervals, relations, operators_print(opIndex), iaId, length(schedPerf.procTime), sum(schedPerf.procTime), mean(schedPerf.procTime), std(schedPerf.procTime), length(schedPerf.iterations), sum(schedPerf.iterations), mean(schedPerf.iterations), std(schedPerf.iterations));
          fclose(logfile);
        end
      end
    end
  end
end